/**
 * 
 *	翰迪数据
 * Copyright (c) 2013-2018 Handy-data,Inc.All Rights Reserved.
 */
package com.handydata.antifraud.crypt.impl;

import com.alibaba.fastjson.JSON;
import com.handydata.antifraud.crypt.AbsCrypto;
import com.handydata.antifraud.crypt.MessageCryptoHandler;
import com.handydata.antifraud.enums.RiskReturnEnum;
import com.handydata.antifraud.util.ExceptionUtil;
import com.handydata.common.util.crypto.CryptoToStringUtil;
import com.handydata.common.util.crypto.MD5Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.Base64Utils;


/**
 * 使用rsa加密key，des加密值的加解密处理器
 * @author guolong
 * @version $Id: SxjCryptoHandler.java, v 0.1 2018年3月8日 下午3:47:14 apple Exp $
 */
@Component("messageCryptoHandler")
public class RsaEncKeyDesEncValCryptoHandler implements MessageCryptoHandler {

    private static Logger logger = LoggerFactory.getLogger(RsaEncKeyDesEncValCryptoHandler.class);
    /** 
     * @see com.handydata.antifraud.crypt.MessageCryptoHandler#decode(com.handydata.antifraud.crypt.AbsCrypto)
     */
    @Override
    public boolean decode(AbsCrypto crypto) {
        CryptoReq cryptoReq = (CryptoReq)crypto;
        try {
            String decDeskey = ExceptionUtil.of(() -> CryptoToStringUtil.decryptByPubKeyFromBase64(cryptoReq.getDesKey(), cryptoReq.getPublicKey()), RiskReturnEnum.DECRYPT_DATA_ERROR).get();
            String content = ExceptionUtil.of(() -> CryptoToStringUtil.decryptDESFromBase64(cryptoReq.getContent(), decDeskey), RiskReturnEnum.DECRYPT_DATA_ERROR).get();
            
            String contentAndkey = Base64Utils.encodeToString(content.getBytes(cryptoReq.getCharset())).concat(decDeskey);
            String genSign = MD5Util.digest(contentAndkey);
            
            if(genSign.equalsIgnoreCase(cryptoReq.getSign())) {
            	cryptoReq.setClearTextMap(ExceptionUtil.of(() -> JSON.parseObject(content), RiskReturnEnum.PARSE_JSON_ERROR).get());
                return true;
            } else {
            	cryptoReq.setMsg(RiskReturnEnum.CHECK_SIGN_ERROR.toString());
            }
            
        } catch (Exception e) {
            logger.error("Decode {} ciper text occur error", crypto, e);
            cryptoReq.setMsg(RiskReturnEnum.of(e.getMessage()).toString());
        }
        return false;
    }

    /** 
     * @see com.handydata.antifraud.crypt.MessageCryptoHandler#encode(com.handydata.antifraud.crypt.AbsCrypto)
     */
    @Override
    public boolean encode(AbsCrypto crypto) {
        CryptoReq cryptoReq = (CryptoReq)crypto;
        try {
            String encDeskey = ExceptionUtil.of(() -> CryptoToStringUtil.encryptByPriKeyToBase64(cryptoReq.getDesKey(), cryptoReq.getPrivateKey()), RiskReturnEnum.ENCRYPT_DATA_ERROR).get();
            String content = ExceptionUtil.of(() -> CryptoToStringUtil.encryptDESToBase64(cryptoReq.getContent(), cryptoReq.getDesKey()), RiskReturnEnum.ENCRYPT_DATA_ERROR).get();
            
            String contentAndkey = Base64Utils.encodeToString(cryptoReq.getContent().getBytes(cryptoReq.getCharset())).concat(cryptoReq.getDesKey());
            String genSign = MD5Util.digest(contentAndkey);
            
            cryptoReq.setEncryptObject(encDeskey + "|" + content + "|" + genSign);
            
            return true;
            
        } catch (Exception e) {
            logger.error("encode {} ciper text occur error",crypto, e);
            cryptoReq.setMsg(RiskReturnEnum.of(e.getMessage()).toString());
        }
        return false;
    }
    
}
